
import unittest

def safe_int(obj):
    try:
        return int(obj)
    except (ValueError,TypeError):
        return "ErrorCast"
    
def throw_exception(value1,value2,value3):
    """
    throw tuple as the argument of exception
    """
    raise Exception(value1,value2,value3)
    
def not_implemented_method():
    raise NotImplementedError("Test")

class TestException(unittest.TestCase):
    def test_sample1(self):
        self.assertEqual(3,safe_int(3.14))
        self.assertEqual("ErrorCast",safe_int("3.14"))
        
    def test_error_message(self):
        try:
            not_implemented_method()
        except NotImplementedError as error:
            self.assertEqual("Test",str(error))
            
    def test_using_tuple_argument(self):
        filename = "noexist.txt"
        
        try:
            fr = open(filename,"rt")
        except IOError,error:
            self.assertEqual(2,len(error.args))
            self.assertEqual(error[0],error.errno)
            self.assertEqual(error[1],error.strerror)
            # although IOError will have "filename" attribute, but that attribute will not be included in the tuuple
            self.assertEqual(filename,error.filename)
        else:
            self.fail("an exception is expected")
            
    def test_tuple_argument(self):
        """
        test the usage that use tuple as the argument of exception
        """
        try:
            throw_exception(1,"cheka",3.14)
        except Exception as error:
            self.assertTrue(isinstance(error,Exception))
            
            arg1,arg2,arg3 = error # __getitem__ has been overriden, so can retrieve values directly
            self.assertEqual(1,arg1)
            self.assertEqual("cheka",arg2)
            self.assertAlmostEqual(3.14,arg3)
        else:
            self.fail("it should throw out an exception")
        

if __name__ == "__main__":
    unittest.main()
    